package com.eflow.model.groovy;

import com.eflow.model.api.IGroovyScriptEngine;
import com.eflow.model.api.IScript;
import com.eflow.model.utils.SpringUtils;
import groovy.lang.GroovyShell;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import static com.eflow.model.e.BpmConst.PROCESS_LISTENER_TYPE;

/**
 * 脚本引擎用于执行groovy脚本。<br/>
 * 实现了IScript接口的类。 可以在脚本中使用。
 */
@Component
public class GroovyScriptEngine implements IGroovyScriptEngine {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private GroovyBinding groovyBinding = new GroovyBinding();
    @Autowired
    private ObjectProvider<IScript> scripts;
    @Override
    public void execute(String script) {
        executeObject(script, null);
    }

    @Override
    public void execute(String script, Map<String, Object> vars) {
        executeObject(script, vars);
    }

    @Override
    public boolean executeBoolean(String script, Map<String, Object> vars) {
        return (Boolean) executeObject(script, vars);
    }

    @Override
    public String executeString(String script, Map<String, Object> vars) {
        return (String) executeObject(script, vars);
    }


    @Override
    public int executeInt(String script, Map<String, Object> vars) {
        return (Integer) executeObject(script, vars);
    }

    @Override
    public float executeFloat(String script, Map<String, Object> vars) {
        return (Float) executeObject(script, vars);
    }

    @Override
    public Object executeObject(String script, Map<String, Object> vars) {
        groovyBinding.setThreadVariables(vars);

        if(logger.isDebugEnabled()) {
        	logger.debug("执行:{}", script);
        	logger.debug("variables:{}",vars+"");
        }

        GroovyShell shell = new GroovyShell(groovyBinding);

        script = script.replace("&apos;", "'").replace("&quot;", "\"")
                .replace("&gt;", ">").replace("&lt;", "<")
                .replace("&nuot;", "\n").replace("&amp;", "&");

        Object rtn = shell.evaluate(script);
        return rtn;
    }



    @PostConstruct
    public void init() {
        Iterator<IScript> iterator = scripts.iterator();
        while(iterator.hasNext()) {
            IScript next = iterator.next();
            groovyBinding.setProperty(next.name(),next);
        }
    }
}
